/* bpftrace execsnoop.bt */
# https://github.com/bpftrace/bpftrace/blob/master/tools/execsnoop.bt


/* 过滤某进程创建的所有子进程 */
#ifndef BPFTRACE_HAVE_BTF
#include <linux/sched.h>
#endif

BEGIN
{
        printf("%-15s %-7s %-7s %s\n", "TIME", "PID", "PPID", "ARGS");
}

tracepoint:syscalls:sys_enter_exec*
{
        $task = (struct task_struct *)curtask;
        if ($task->real_parent->pid == 469813) {
            printf("%15s %-7d %-7d ", strftime("%H:%M:%S.%f", nsecs), pid, $task->real_parent->pid);
            join(args->argv);
        }
}

/* 打印所有执行进程的时间 */
#!/usr/bin/bpftrace

// 定义一个映射，用于存储每个进程的开始时间
BEGIN {
    printf("Tracking execution times for processes...\n");
}

// 监控 execve 系统调用，记录进程启动时间
tracepoint:syscalls:sys_enter_execve
{
    // 将当前时间（以纳秒为单位）记录到 `start_time` 映射中，键为 PID
    @start_time[pid] = nsecs;
    @comm_name[pid] = str(args->argv[0])
}

// 监控进程退出，计算执行时间
tracepoint:sched:sched_process_exit
{
    // 如果当前进程有开始时间记录
    if (@start_time[pid]) {
        // 计算执行时间（当前时间 - 启动时间）
        $duration = nsecs - @start_time[pid];
        $comm = @comm_name[pid];

        // 输出进程 PID 和执行时间（以秒为单位）
        printf("Process %s executed for", $comm);
        printf("%d ms\n", $duration / 1000000);

        // 删除该进程的开始时间记录
        delete(@start_time[pid]);
    }
}